<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Streams of Data
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora039.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora041.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Streams of Data</H2>
<A NAME="subsec-streams"></A>
<A NAME="@fonctions137"></A>
<A NAME="@fonctions138"></A>
<A NAME="@concepts114"></A>
Streams are (potentially infinite) sequences containing elements of
the same kind. The evaluation of a part of a stream is done on
demand, whenever it is needed by the current computation. A stream is
therefore a lazy data structure. <BR>
<BR>
The <I>stream</I> type is an abstract data type; one does not need to
know how it is implemented. We manipulate objects of this type using
constructor functions and destructor 
(or selector) functions. For the convenience of the user, Objective CAML has simple
syntactic constructs to construct streams and to access their
elements. <BR>
<BR>


<H3> Warning </H3> <HR>

Streams are an extension of the language, not part of the stable
core of Objective CAML.


<HR>

<BR>
<BR>
<A NAME="toc55"></A>
<H3> Construction</H3>The syntactic sugar to construct streams is inspired by that for lists
and arrays. The empty stream is written:


<PRE><BR># <CODE>[&lt;</CODE><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>- : 'a Stream.t = &lt;abstr&gt;</CODE><BR>

</PRE>
<BR>
<BR>
One may construct a stream by enumerating its elements, preceding each
one with an with a single quote (character <TT>'</TT>): 


<PRE><BR># <CODE>[&lt;</CODE><CODE> </CODE><CODE>'</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>4</CODE><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>- : int Stream.t = &lt;abstr&gt;</CODE><BR>

</PRE>
<BR>
<BR>
Expressions not preceded by an apostrophe are considered to be
sub-streams:


<PRE><BR># <CODE>[&lt;</CODE><CODE> </CODE><CODE>'</CODE><CODE>0</CODE>;<CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE><CODE> </CODE><CODE>&gt;]</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>4</CODE><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>- : int Stream.t = &lt;abstr&gt;</CODE><BR># <B>let</B><CODE> </CODE>s1<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>s1;<CODE> </CODE><CODE>'</CODE><CODE>4</CODE><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>- : int Stream.t = &lt;abstr&gt;</CODE><BR># <B>let</B><CODE> </CODE>concat_stream<CODE> </CODE>a<CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>a<CODE> </CODE>;<CODE> </CODE>b<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>val concat_stream : 'a Stream.t -&gt; 'a Stream.t -&gt; 'a Stream.t = &lt;fun&gt;</CODE><BR># concat_stream<CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE><CODE>'</CODE><CODE>"if"</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>"c"</CODE>;<CODE>'</CODE><CODE>"then"</CODE>;<CODE>'</CODE><CODE>"1"</CODE><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE><CODE>'</CODE><CODE>"else"</CODE>;<CODE>'</CODE><CODE>"2"</CODE><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>- : string Stream.t = &lt;abstr&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The <TT>Stream</TT> module also provides other construction functions.
For instance, the functions <TT>of_channel</TT> and
<TT>of_string</TT> return a stream containing a sequence of
characters, received from an input stream or a string. 
<A NAME="@fonctions139"></A>
<A NAME="@fonctions140"></A>


<PRE><BR># Stream.of_channel<CODE> </CODE>;;<BR><CODE>- : in_channel -&gt; char Stream.t = &lt;fun&gt;</CODE><BR># Stream.of_string<CODE> </CODE>;;<BR><CODE>- : string -&gt; char Stream.t = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The deferred computation of streams makes it possible to manipulate
infinite data structures in a way similar to the type <I>'a enum</I>
defined on page&nbsp;<A HREF="book-ora039.html#C-Styles-ens">??</A>. We define the stream of
natural numbers by its first element and a function calculating the
stream of elements to follow: 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>nat_stream<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'n<CODE> </CODE>;<CODE> </CODE>nat_stream<CODE> </CODE><TT>(</TT>n<CODE>+</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>val nat_stream : int -&gt; int Stream.t = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>nat<CODE> </CODE><CODE>=</CODE><CODE> </CODE>nat_stream<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val nat : int Stream.t = &lt;abstr&gt;</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc56"></A>
<H3> Destruction and Matching of Streams</H3>
<A NAME="@concepts115"></A>The primitive <TT>next</TT> permits us to evaluate, retrieve, and
remove the first element of a stream, all at once:
<A NAME="@fonctions141"></A>


<PRE><BR># <B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE><B>do</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_int<CODE> </CODE><TT>(</TT>Stream.next<CODE> </CODE>nat<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"  "</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;;<BR><CODE>0  1  2  3  4  5  6  7  8  9  10  - : unit = ()</CODE><BR># Stream.next<CODE> </CODE>nat<CODE> </CODE>;;<BR><CODE>- : int = 11</CODE><BR>

</PRE>

When the stream is exhausted, an exception is raised.


<PRE><BR># Stream.next<CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>Uncaught exception: Stream.Failure</CODE><BR>

</PRE>
<BR>
<BR>
To manipulate streams, Objective CAML offers a special-purpose matching
construct called destructive matching. The value matched is
calculated and removed from the stream. There is no notion of
exhaustive match for streams, and, since the data type is lazy and
potentially infinite, one may match less than the whole stream. The
syntax for matching is: 
<A NAME="@fonctions142"></A>
<A NAME="@fonctions143"></A>
<A NAME="@fonctions144"></A>


<H3> Syntax </H3> <HR>


 <B>match</B> <I>expr</I> <B>with parser</B> 
 <B>[&lt;</B> <B>'</B><I>p</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> ...<B>&gt;]</B> <B>-&gt;</B> <I>expr</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB>
 <B>|</B> ... 


<HR>

<BR>
<BR>
The function <TT>next</TT> could be written:


<PRE><BR># <B>let</B><CODE> </CODE>next<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'x<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val next : 'a Stream.t -&gt; 'a = &lt;fun&gt;</CODE><BR># next<CODE> </CODE>nat;;<BR><CODE>- : int = 12</CODE><BR>

</PRE>

Note that the enumeration of natural numbers picks up where we left it
previously. <BR>
<BR>
As with function abstraction, there is a syntactic form matching a
function parameter of type <I>Stream.t</I>. 


<H3> Syntax </H3> <HR>

 <B>parser</B> <I>p</I> -&gt; ...


<HR>


The function <TT>next</TT> can thus be rewritten:


<PRE><BR># <B>let</B><CODE> </CODE>next<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>parser</B><CODE> </CODE><CODE>[&lt;</CODE>'x<CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val next : 'a Stream.t -&gt; 'a = &lt;fun&gt;</CODE><BR># next<CODE> </CODE>nat<CODE> </CODE>;;<BR><CODE>- : int = 13</CODE><BR>

</PRE>
<BR>
<BR>
It is possible to match the empty stream, but take care: the stream
pattern <CODE>[&lt;&gt;]</CODE> matches every stream. In fact, a stream
<TT>s</TT> is always equal to the stream <CODE>[&lt;</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE>;<CODE> </CODE>s<CODE> </CODE><CODE>&gt;]</CODE>.
For this reason, one must reverse the usual order of matching: 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>it_stream<CODE> </CODE>f<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'x<CODE> </CODE>;<CODE> </CODE>ss<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>f<CODE> </CODE>x<CODE> </CODE>;<CODE> </CODE>it_stream<CODE> </CODE>f<CODE> </CODE>ss<BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>val it_stream : ('a -&gt; 'b) -&gt; 'a Stream.t -&gt; unit = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>print_int1<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>print_int<CODE> </CODE>n<CODE> </CODE>;<CODE> </CODE>print_string<CODE>" "</CODE><CODE> </CODE>;;<BR><CODE>val print_int1 : int -&gt; unit = &lt;fun&gt;</CODE><BR># it_stream<CODE> </CODE>print_int1<CODE> </CODE><CODE>[&lt;</CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>1 2 3 - : unit = ()</CODE><BR>

</PRE>

Since matching is destructive, one can equivalently write: 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>it_stream<CODE> </CODE>f<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'x<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>f<CODE> </CODE>x<CODE> </CODE>;<CODE> </CODE>it_stream<CODE> </CODE>f<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>val it_stream : ('a -&gt; 'b) -&gt; 'a Stream.t -&gt; unit = &lt;fun&gt;</CODE><BR># it_stream<CODE> </CODE>print_int1<CODE> </CODE><CODE>[&lt;</CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>1 2 3 - : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>
Although streams are lazy, they want to be helpful, and never refuse
to furnish a first element; when it has been supplied once it is lost.
This has consequences for matching. The following function is an
attempt (destined to fail) to display pairs from a stream of integers,
except possibly for the last element.


<PRE><BR># <B>let</B><CODE> </CODE>print_int2<CODE> </CODE>n1<BR><CODE> </CODE>n2<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE>print_string<CODE> </CODE><CODE>"("</CODE><CODE> </CODE>;<CODE> </CODE>print_int<CODE> </CODE>n1<CODE> </CODE>;<CODE> </CODE>print_string<CODE> </CODE><CODE>","</CODE><CODE> </CODE>;<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE>print_int<CODE> </CODE>n2<CODE> </CODE>;<CODE> </CODE>print_string<CODE> </CODE><CODE>")"</CODE><CODE> </CODE>;;<BR><CODE>val print_int2 : int -&gt; int -&gt; unit = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>print_stream<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'x;<CODE> </CODE>'y<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_int2<CODE> </CODE>x<CODE> </CODE>y;<CODE> </CODE>print_stream<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'z<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_int1<CODE> </CODE>z;<CODE> </CODE>print_stream<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_newline()<CODE> </CODE>;;<BR><CODE>val print_stream : int Stream.t -&gt; unit = &lt;fun&gt;</CODE><BR># print_stream<CODE> </CODE><CODE>[&lt;</CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE><CODE>&gt;]</CODE>;;<BR><CODE>(1,2)Uncaught exception: Stream.Error("")</CODE><BR>

</PRE>
<BR>
<BR>
The first two two members of the stream were displayed properly, but
during the evaluation of the recursive call (print_stream<CODE> </CODE><CODE>[&lt;</CODE><CODE>3</CODE><CODE>&gt;]</CODE>),
the first pattern found a value for <TT>x</TT>, which was
thereby consumed. There remained nothing more for <TT>y</TT>. This
was what caused the error. In fact, the second pattern is useless,
because if the stream is not empty, then first pattern always begins
evaluation. <BR>
<BR>
To obtain the desired result, we must sequentialize the matching:


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>print_stream<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'x<CODE> </CODE><CODE>&gt;]</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'y<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_int2<CODE> </CODE>x<CODE> </CODE>y;<CODE> </CODE>print_stream<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_int1<CODE> </CODE>x;<CODE> </CODE>print_stream<CODE> </CODE>s<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_newline()<CODE> </CODE>;;<BR><CODE>val print_stream : int Stream.t -&gt; unit = &lt;fun&gt;</CODE><BR># print_stream<CODE> </CODE><CODE>[&lt;</CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE><CODE>&gt;]</CODE>;;<BR><CODE>(1,2)3 </CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>
If matching fails on the first element of a pattern however, then we
again have the familiar behavior of matching: 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>print_stream<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE>'y<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_int2<CODE> </CODE><CODE>1</CODE><CODE> </CODE>y;<CODE> </CODE>print_stream<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'z<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_int1<CODE> </CODE>z;<CODE> </CODE>print_stream<CODE> </CODE>s<BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>print_newline()<CODE> </CODE>;;<BR><CODE>val print_stream : int Stream.t -&gt; unit = &lt;fun&gt;</CODE><BR># print_stream<CODE> </CODE><CODE>[&lt;</CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>(1,2)3 </CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>

<H4> The Limits of Matching</H4>
Because it is destructive, matching streams differs from matching on
sum types. We will now illustrate how radically different it can be. <BR>
<BR>
We can quite naturally write a function to compute the sum of the
elements of a stream:


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>sum<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'n;<CODE> </CODE>ss<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>n<CODE>+</CODE><TT>(</TT>sum<CODE> </CODE>ss<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val sum : int Stream.t -&gt; int = &lt;fun&gt;</CODE><BR># sum<CODE> </CODE><CODE>[&lt;</CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>4</CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>- : int = 10</CODE><BR>

</PRE>

However, we can just as easily consume the stream from the inside,
naming the partial result: 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>sum<CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>s<CODE> </CODE><B>with</B><CODE> </CODE><B>parser</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[&lt;</CODE><CODE> </CODE>'n;<CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE>sum<CODE> </CODE><CODE>&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE>n<CODE>+</CODE>r<BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>[&lt;&gt;]</CODE><CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val sum : int Stream.t -&gt; int = &lt;fun&gt;</CODE><BR># sum<CODE> </CODE><CODE>[&lt;</CODE><CODE>'</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>3</CODE>;<CODE> </CODE><CODE>'</CODE><CODE>4</CODE><CODE>&gt;]</CODE><CODE> </CODE>;;<BR><CODE>- : int = 10</CODE><BR>

</PRE>
<BR>
<BR>
We will examine some other important uses of streams in
chapter&nbsp;<A HREF="index.html#chap-AlexS">11</A>, which is devoted to lexical and syntactic
analysis. In particular, we will see how consuming a stream from the
inside may be profitably used. <BR>
<BR>
<BR>
<BR>

<BR>
<BR>
 <BR>
<BR>
<HR>
<A HREF="book-ora039.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora041.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
